Content of this chapter is also included inside of the~application. It is
available in the~form of formatted HTML help with searching, indexing and
navigation capabilities.

\section{Introduction}
This guide is intented to give the~developers picture about internal structures
of the~system and about the~points of extension.

It is assumed that the~reader of this documents if familiar with object oriented
development, Java programming language and with Eclipse plugin development
practices.

You can provide your new elements by providing the~users with the~separate
plugin or with a~set of plugins bundled into the~feature. They can install it by
simply adding the~plugin to the~plugin folder of their installation. If
the~plugin is recognized by the~system can be easily checked under the~details of the~about dialog.

\section{Session Elements}
Before we start with the~description on how to add new elements to
the~application, we would like to say something about the~Environment and API.
Objects that basically interconnects everything in the~runtime of the~Session.
All the~objects that will be mentioned in this section are located in
the~\texttt{net.\-zarubsys.\-robotplayground.\-core} plugin.

Environment is passed to every element that can be added to the~Session during the~initialization time. It is connected to the~API and its purpose is to
provide communication and logging facility mostly but not exclusively for
Modules. Description of the~methods available follows.

\noindent
\texttt{API getAPI()} Provides access to the~API object.

\noindent
\texttt{String getLogPath()} Provides path to the~current Session log.

\noindent
\texttt{void registerStopListener(IStopListener listener)} Allows to register
a~stop listener. Stop listener will be notified when the~execution is to be stopped for any reason. It can be either simply end of the~programs execution or
forced stop caused for example by user.

\noindent
\texttt{void dispatchNotification(IModule<? extends IDevice, ? extends
IModuleConf\-iguration> module, INotificationCause cause)} Allows Modules to
dispatch any notification they want. It can be information about the~movement of the~Device, change of the~parameter or just a~timer. This notification will be
passed to all Monitors that are connected with this module so they can react
properly.

\noindent
\texttt{void stop(Object caller, String message)} Stops the~whole simulation and
triggers stop notifications. This method should be called when any element of the~Session needs to stop the~execution.

API on the~other hand is to be used mostly for Modules invocation. It also
provides access to the~Environment so if you have one, you can always get the~other. While Modules obtain Environment during the~initialization, they can get the~API from it and use it to invoke methods on other Modules. This approach is a~little bit out of the~box but it is intentionally allowed in order to avoid
unnecessary creation of Monitors for simple operations.

\noindent
\texttt{Object callFunction(String moduleName, String functionName, List<Object>
values)} This method provides facility to call the~published function inside of a~Module. Parameters must be passed correctly depending on needs of the~Module.
How is the~call handled and values are returned depends on the~implementation of the~Module you want to call.

\subsection{Adding New Device}
As described in the~user's documentation, Device represents the~lowest layer of
abstraction over the~real device or the~simulation. Do not add complex logick
and macro functions into the~device. These belong to the~proper Module. Device
should handle just the~communication and conversion of the~state and commands
available on the~device to the~Java world. If it is a~simulation, it should hold the~state of the~simulated object and provide basic access to commands and to
information gathering.

If you want to add new Device into the~system, you have to implement the~\texttt{IDevice<T extends IDeviceConfiguration>} interface. If you want to
provide some kind of the~configuration to the~Device, implement
\texttt{IDeviceConfiguration} interface and parametrize with it your Device
implementation. If not there is the~\texttt{EmptyDeviceConfiguration} ready for
your convenience. There are three methods in \texttt{IDevice} interface you have
to implement. You should also have non-parametric constructor in your
implementation.

\noindent
\texttt{String getId()} Should return a~UNIQUE id of the~Device.

\noindent	
\texttt{void init(T configuration, Environment env)} Passes the~configuration of the~proper type and reference to the~environment to the~newly created instance
of your Device. In this method, you should do the~simulation or hardware
initialization.

\noindent
\texttt{void close()} This method is called when the~simulation ends. You should
clean up any resources you gathered during the~simulation.

Besides the~methods and the~constructor described above, you can provide any
public methods you want. Modules will have direct access to the~Device instance
so they can use them. Be sure to encapsulate any dangerous functionality.

Every new Device must be plugged into the~extension point
\texttt{net.zarubsys.robotplay\-ground.core.devices}. The~extension point
is self-explanatory.

\subsection{Adding New Module}
Module is a~higher level of abstraction over the~Device or it can also represent
some abstract tool. It must refer to some type of the~Device anyway. If you
don't want to use any, use \texttt{NullDevice}. Modules are configured. If you
want to use some configuration, create an~implementation of
\texttt{IModuleConfiguration} interface or use the~\texttt{EmptyModuleConfiguration} implementation. You have to implement
following methods.

\noindent	
\texttt{void init(D device, C configuration, Environment env)} Provides the~data
for initialization. An~instance of the~Device and reference to the~shared
Environment.
In this method you are expected to initialize every resource needed. The~instance of the~Device you get here is already initialized so you
can start calling some methods here.

\noindent	
\texttt{Set<FunctionDescriptor> getAllFunctions()} This method must return
function descriptors of all published functions of this module.

\noindent	
\texttt{Object callFunction(String functionName, List<Object> values)} If
this method gets invoked with proper function name and
parameters must invoke the~internal function and return its result.

\noindent	
\texttt{void close()} You should clean every resorurce you gather during
the~runtime.

\noindent	
\texttt{String getId()} This method must return UNIQUE id of this module.

\noindent	
\texttt{String getRequiredDevice()} This method must return an~id of the~Device
using which it is parametrized.

	
If you don't want to implement the~\texttt{callFunction} method and you would
rather just provide some functionality, there is abstract implementation of the~Module interface called \texttt{AbstractModule} which takes care about the~calls
dispatching. Just implement your public methods and then annotate them using the~\texttt{@Function(description = "")} annotation and annotate every parameter
by \texttt{@Param(name = "")}. These methods will be now invokable. You can also
register any other method using the~\texttt{registerFunction(FunctionDescriptor
fd, Method m, Object invocationObject)} method if you cannot annotate for some
reason.

Every new Module must be plugged into the~extension point
\texttt{net.\-zarubsys.\-robotplay\-ground.\-core.\-modules}. The~extension
point is self-explanatory.
	

\subsection{Adding New Monitor}
To see what the~actually is, consult the~user's guide. If you want to implement
new Monitor, you should implement the~\texttt{IMonitor} interface. This
interface consist of following methods.

\noindent	
\texttt{List<String> getRequiredModules()} This method should return a~list of
ids of Modules that this Monitor needs to use.

\noindent	
A method \texttt{void init(List<IModule<? extends IDevice, ? extends
IModuleConfiguration>> modules, Environment env)} is invoked after
the~instantiation of the~class. Modules specified in the~previous method are passed in the~same order and you also get access to the~Environment. Initialize
everything you need here.

\noindent	
\texttt{void notify(IModule<?, ?> module, INotificationCause cause)} This method
is called once some of the~Modules specified in the~first method fires a
notification. You should notify all listeners registered in the~last method if
there is some action to be taken.

\noindent	
\texttt{String getId()} This method should return a~UNIQUE id of this Monitor.

\noindent	
\texttt{void registerMonitorListeners(List<IMonitorListener> listeners)}
The~purpose of this method is to register listeners to this Monitor.
You should notify them every time something interesting happens, mostly when the~\texttt{notify}
method gets called.

Every new Monitor must be plugged into the~extension point
\texttt{net.\-zarubsys.\-robotplay\-ground.\-core.\-monitors}. The~extension
point is self-explanatory.
	
	
\subsection{Adding New Program}
If you want to implement your own programming language or just connect some
existing language, you need to implement interface \texttt{IProgram}.
Program can be configured by implementing \texttt{IProgramConfiguration}
interface and using it as a~generics parameter. The~Program interface is simple
and consist only of two methods.

\noindent
\texttt{void getId()} This method should return a~UNIQUE id of this Program.

\noindent
\texttt{void run(API api, T configuration, Environment env)} This method gets
called when the~Program should be executed. You can use API to pass the~calls to
Modules, configuration if you want and Environment should be used to register
a~stop listener and terminate the~execution in the~event of stop beeing raised.

\subsection{GUI Providers}
Until now we were talking just about the~backend. If you want your user to be
able to use the~elements you give them, you must also create a~GUI provider for
each of them. This provider takes case about the~UI part. Provides image,
description, invokes validation and adds/removes the~element from the~Session.

To do this, you need to implement \texttt{ISystemObjectGUIProvider} interface
with following methods.

\noindent
\texttt{Image getImage(String id)} This method should provide an~image of size
64 x 64 pixels as the~SWT resource. Do not forget that SWT resources are not
disposed when garbage collected.

\noindent
\texttt{String getDescription(String id)} This method can provide static
description of the~element. Meaning that it is not yet in the~Session so you
don't know the~rest of the~environment yet.

\noindent
\texttt{String getDescription(Session session, int index)} This method should
provide dynamic description. Meaning that now you have the~Session so you know
more about the~environment of this element.

\noindent
\texttt{SystemObjectGUIProviderClass getProviderClass()} Returns one of
the~provider classes (DEVICE, MODULE, MONITOR or PROGRAM) based on what this provider represents.

\noindent
\texttt{int addObjectToSession(Session session, String id)} Adds object to
the~given session into the~appropriate class of objects and return the~position of the~newly added element.

\noindent
\texttt{boolean reconfigure(Session session, int index)} Runs
the~reconfiguration wizard if this applies for this provider.

\noindent
\texttt{boolean isConfigurable(String id)} Returns true if this element has some
meaningful configuration and false otherwise.

\noindent
\texttt{boolean remove(Session session, int index)} Removes this element from
the~Session and the~index in its class of elements.

\noindent
\texttt{String validate(Session session, int index)} Runs the~validation
whatever that might mean for this provider. Returns the~error message if some or
null when everything is ok.

Your provider might also implement some additional interfaces to provide
extended functionality.

Implement \texttt{IOpenable} and its simple method to provide opening of the~resource on double click on the~icon.

Implement \texttt{IRunListener} if you want to be notified when the~Session is
executed.

Implement \texttt{ISystemObjectChangeNotifier} if you want to be able to cause
revalidation of the~element and thus the~Session on some change of the~underlying resource. You should register these for Programs, Maps and other
resources that are modified in the~UI.

If you implement a~simple Module that has no configuration, you can use the~abstract implementation of the~\texttt{ISystemObjectGUIProvider} interface
called \texttt{AbstractSimpleModuleGUIProvider} which takes care of the~most of the~work for you. You should check it out.

This provider must be contributed into the~extension point
\texttt{net.\-zarubsys.\-robotplay\-ground.\-gui.\-session.\-systemObjectGUIProviders}.

\section{Adding New Functions to the~Script Program} The~implementation of Program called Script Program is described in detail in the~user's guide. You can find many useful functions there. Still you might need
to implement your own functions to make your life easier.

New function can be created by implementing of the~\texttt{IScriptFunction}
interface and contributing the~implementation to the~\texttt{net.\-zarubsys.\-commons.\-scripting.\-scriptFunctions} extension point. The~interface consist from the~following methods.

\noindent
\texttt{public String getName()} Returns the~name of the~function as it will be
used in the~language. Be sure to make it unique.

\noindent
\texttt{public int getMinArgsNum()} Returns minimal count of arguments that this
function takes or 0 when it takes no arguments;

\noindent
\texttt{public int getMaxArgsNum()} Returns maximal count of argument that this
function takes. If all arguments are obligatory, returns the~same number as
the~previous method. If there are no arguments returns 0. If there is unlimited
count of arguments, returns -1.

\noindent
The~real execution takes place in \texttt{public Object
execute(ScriptingEnvironment env, List<ParsedStatement> args) throws
ScriptingException} method. Scripting environment can be used to access the~stop
flag and is also useful for evaluation of arguments. In the~\texttt{args} parameter, you get the~parameters that are given to this function. These parameters are raw.
They are not evaluated yet. If you want to use them, you must evaluate them
first by calling the~\texttt{Object execute(env)} on the~\texttt{ParsedStatement}. After that the~returned object represents the~real
value of the~parameter. At the~end you can return null or any object you wish.
You shouldn't manipulate the~variable pools directly although you can gain
access to them using the~Environment.

After the~contribution, you can use your new function out of the~box. Enjoy.

